home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
MOU_ROUT.ARJ
/
PAGEFLIP.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1990-05-08
|
5KB
|
113 lines
From usc!snorkelwacker!ira.uka.de!news Tue May 8 12:02:49 PDT 1990
Article 2637 of comp.lang.pascal:
Path: jarthur!usc!snorkelwacker!ira.uka.de!news
>From: s_rohrbacher
Newsgroups: comp.lang.pascal
Subject: Re: flicker-free animation with TP
Message-ID: <90.127.13:27:55@ira.uka.de>
Date: 7 May 90 20:24:27 GMT
Sender: news@ira.uka.de (USENET News System)
Reply-To: s_rohrbacher
Organization: University of Karlsruhe, FRG
Lines: 96
Some days ago, one of you asked for a solution to do fast flicker-free
animation in TurboPascal. I myself had the same problem and circumvented it by
a simple technique called "page-flipping": nearly every graphic card has 2
independent graphic pages, so it is possible to draw at one page while showing
the other. If the "background" page is finished, you just "flip" the pages:
thus, at any time all actions take place in the background and you get a smooth
animation!
In TP, you choose the visible page with "SetVisualPage" and the working page
with "SetActivePage". - Take the following program as an example: it animates a
hatched square, either with or without page-flipping (adapt proc. "Initialize"
if you have a Hercules instead of an EGA/VGA):
PROGRAM page_flipping_demo; {by Kai Rohrbacher, TP 5.0, 4/25/90}
USES Crt,Graph;
CONST seeing_page:Word=0; {number of actual seen page}
VAR GraphDriver,GraphMode,x,y,xold,yold,xtemp,ytemp:Integer;
Sprite:Pointer; {pointer to sprite-data}
ch:char;
WITH_PAGE_FLIPPING:Boolean; {demonstration mode}
PROCEDURE Initialize; {set any graphic-mode with 2 pages; here EGA}
BEGIN
GraphDriver:=EGA; GraphMode:=EGAHi;
InitGraph(GraphDriver,GraphMode,'');
IF GraphResult<>grOK THEN BEGIN Writeln('No EGA!'); Halt(1) END;
END;
PROCEDURE initialize_flip; {clear pages; show one, work on the other}
BEGIN
setactivepage(0); cleardevice;
outtextxy(100,0,'Page 0 - Use I,J,K,M, Q=Quit');
setactivepage(1); cleardevice;
outtextxy(100,0,'Page 1 - Use I,J,K,M, Q=Quit');
setactivepage(1-seeing_page); setvisualpage(seeing_page)
END;
PROCEDURE flip; {exchange active & visible page}
BEGIN
setactivepage(seeing_page); seeing_page:=1-seeing_page;
setvisualpage(seeing_page);
END;
PROCEDURE update_sprite; {works totally on background page!}
BEGIN
IF (xold<>-1) AND (yold<>-1) THEN PutImage(xold,yold,sprite^,XORput);
PutImage(x,y,sprite^,XORput)
END;
BEGIN {main}
Write('With (1) or without (2) pageflipping? ');
REPEAT ch:=UpCase(readkey) UNTIL ch in ['1','2'];
WITH_PAGE_FLIPPING:=ch='1'; {set mode}
Initialize;
{generate sprite and save it on TP's stack:}
rectangle(0,0,50,50); setFillStyle(Hatchfill,white);
FloodFill(1,1,white); GetMem(sprite,ImageSize(0,0,50,50));
GetImage(0,0,50,50,sprite^); cleardevice;
outtextxy(0,0,'Use I,J,K,M, Q=Quit');
IF WITH_PAGE_FLIPPING THEN initialize_flip;
xold:=-1; yold:=-1; xtemp:=-1; ytemp:=-1; {-1=flag: 'currently not used'}
x:=100; y:=100; {starting point of animation}
REPEAT
ch:=UpCase(readkey);
CASE ch OF {what action?}
'J':dec(x); 'K':inc(x); 'I':dec(y); 'M':inc(y); 'Q':;
ELSE BEGIN sound(1200); delay(100); nosound END
END;
update_sprite; {remove old, draw new}
IF WITH_PAGE_FLIPPING
THEN BEGIN {shift through: x->xtemp->xold, y->ytemp->yoldf}
xold:=xtemp; yold:=ytemp; xtemp:=x; ytemp:=y; flip
END {so after 2 cycles the sprite is cleared from correct page}
ELSE BEGIN xold:=x; yold:=y END; {no flipping=no such mechanism needed}
UNTIL ch='Q';
FreeMem(sprite,ImageSize(0,0,50,50)); closegraph; {end correctly}
END.
The only thing to notice is that you have to store coordinates for 2
cycles to be able to erase a sprite on the correct page.
There remains one last possibility of (minor) flicker: depending on your
PC's BIOS, it may happen that programs flip pages while the cathode ray
is in the midst of displaying data: in that case you have to bypass BIOS
and synchronize switching directly with the "vertical retrace" (the
moment while the cathode ray moves back from the bottom-right to the
upper-left corner). As a time-critical task (the corresponding bit at
port $3DA, Bitmask 8 (or $3BA, Bitmask 128 for HGC) toggles with 50Hz),
you should do that in assembler.
To all of you who hope to program an arcade game completely in TP, be
warned: TP is just to slow to do the job (try to animate -say- 30
sprites at once)! Me too, I had to discover this (3 years ago) -and came
out with a self-written TP-unit, spritedesigner and a lot of integrated
assembler stuff (for the animation itself, background-saving, collision
detection, scrolling and that things).
I am planning to release this package (as shareware) here in FRG very
soon, so if you are interested, watch out!
S_ROHRBACHER@IRAV1.IRA.UKA.DE (Kai Rohrbacher)